package com.oromwin.repos.client;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import org.apache.commons.logging.Log;

import com.oromwin.repos.common.Logger;
import com.oromwin.repos.common.ReposConfig;
import com.oromwin.repos.common.ReposException;

public abstract class AbstractSocketClient implements SocketClient {
    private Log log = Logger.getLog(AbstractSocketClient.class);
    private Socket _socket = null;
    protected void connect() throws ReposException {
        InetAddress addr = null;
        SocketAddress sockaddr = null;
        String hostname = ReposConfig.getInstance().getReposSocketServerIP();
        int timeout = ReposConfig.getInstance().getReposSocketClientTimeout();
        int port = ReposConfig.getInstance().getReposSocketPort();
        try {
            addr = InetAddress.getByName(hostname);
            sockaddr = new InetSocketAddress(addr, port);
            _socket = new Socket();
            _socket.connect(sockaddr, timeout);
        } catch (UnknownHostException e) {
            String message = String.format("Can't connect to server, hostname {%s}", hostname);
            throw ReposException.create(log, e, message);
        } catch (SocketTimeoutException e) {
            String message = String.format("Can't connect to server, timeout {%d}", timeout);
            throw ReposException.create(log, e, message);
        } catch (IOException e) {
            String message = String.format("Can't connect to server, socket {%s}", _socket.toString());
            throw ReposException.create(log, e, message);
        }
    }
    protected void disconnect() throws ReposException {
        try {
            _socket.close();
        } catch (IOException e) {
            String message = String.format("Failed to disconnect socket connection, socket {%s}", _socket.toString());
            throw ReposException.create(log, e, message);
        }
    }
    protected DataOutputStream getDataOutputStream() throws ReposException {
        DataOutputStream dos = null;
        try {
            dos = new DataOutputStream(new BufferedOutputStream(_socket.getOutputStream()));
        } catch (IOException e) {
            String message = String.format("Failed to get output stream, socket {%s}", _socket.toString());
            throw ReposException.create(log, e, message);
        }
        return dos;
    }
    protected DataInputStream getDataInputStream() throws ReposException {
        DataInputStream dis = null;
        try {
            dis = new DataInputStream(new BufferedInputStream(_socket.getInputStream()));
        } catch (IOException e) {
            String message = String.format("Failed to get input stream, socket {%s}", _socket.toString());
            throw ReposException.create(log, e, message);
        }
        return dis;
    }
}
